﻿using System;
using System.ComponentModel;
using Loki;
using Luna.Data.Accounting;
using Luna.Model.Project;

namespace Luna.Model.Accounting
{
    internal class AccountOperation : LunaEntity, IAccountOperation, IAccountOperationData
    {
        #region Properties
        #region  AccountID
        private static PropertyChangedEventArgs _AccountIDChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.AccountID);

        private Guid _AccountID;

        public Guid AccountID
        {
            get
            {
                return _AccountID;
            }

            set
            {
                if (value != _AccountID)
                {
                    _AccountID = value;
                    NotifyChangedAndDirty(_AccountIDChangeArgs);
                }
            }
        }
        #endregion

        #region  CategoryID
        private static PropertyChangedEventArgs _CategoryIDChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.CategoryID);

        private Guid _CategoryID;

        public Guid CategoryID
        {
            get
            {
                return _CategoryID;
            }

            set
            {
                if (value != _CategoryID)
                {
                    _CategoryID = value;
                    NotifyChangedAndDirty(_CategoryIDChangeArgs);
                }
            }
        }
        #endregion

        #region  ProjectID
        private static PropertyChangedEventArgs _ProjectIDChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.ProjectID);

        private Guid? _ProjectID;

        public Guid? ProjectID
        {
            get
            {
                return _ProjectID;
            }

            set
            {
                if (value != _ProjectID)
                {
                    _ProjectID = value;
                    NotifyChangedAndDirty(_ProjectIDChangeArgs);
                }
            }
        }
        #endregion

        #region  Amount
        private static PropertyChangedEventArgs _AmountChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.Amount);

        private decimal _Amount;

        public decimal Amount
        {
            get
            {
                return _Amount;
            }

            set
            {
                if (value != _Amount)
                {
                    _Amount = value;
                    NotifyChangedAndDirty(_AmountChangeArgs);
                }
            }
        }
        #endregion

        #region  Description
        private static PropertyChangedEventArgs _DescriptionChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.Description);

        private string _Description;

        public string Description
        {
            get
            {
                return _Description;
            }

            set
            {
                if (value != _Description)
                {
                    _Description = value;
                    NotifyChangedAndDirty(_DescriptionChangeArgs);
                }
            }
        }
        #endregion

        #region  ExecutionDate
        private static PropertyChangedEventArgs _ExecutionDateChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.ExecutionDate);

        private DateTime _ExecutionDate;

        public DateTime ExecutionDate
        {
            get
            {
                return _ExecutionDate;
            }

            set
            {
                if (value != _ExecutionDate)
                {
                    _ExecutionDate = value;
                    NotifyChangedAndDirty(_ExecutionDateChangeArgs);
                }
            }
        }
        #endregion

        #region  ValueDate
        private static PropertyChangedEventArgs _ValueDateChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.ValueDate);

        private DateTime? _ValueDate;

        public DateTime? ValueDate
        {
            get
            {
                return _ValueDate;
            }

            set
            {
                if (value != _ValueDate)
                {
                    _ValueDate = value;
                    NotifyChangedAndDirty(_ValueDateChangeArgs);
                }
            }
        }
        #endregion

        #region  OperationType
        private static PropertyChangedEventArgs _OperationTypeChangeArgs = ObservableHelper.CreateArgs<AccountOperation>(x => x.OperationType);

        private AccountOperationType _OperationType;

        public AccountOperationType OperationType
        {
            get
            {
                return _OperationType;
            }

            set
            {
                if (value != _OperationType)
                {
                    _OperationType = value;
                    NotifyChangedAndDirty(_OperationTypeChangeArgs);
                }
            }
        }
        #endregion

        public Guid PK
        {
            get { return this.ID; }
            set { ID = value; }
        }

        #region Account
        private IAccount _Account = null;

        public IAccount Account
        {
            get
            {
                if (_Account == null)
                {
                    return ApplicationModel.Accounting.Accounts[_AccountID];
                }
                else
                {
                    return _Account;
                }
            }

            set
            {
                if (_Account == null)
                {
                    if (value == null)
                    {
                        _AccountID = Guid.Empty;
                    }
                    else
                    {
                        _AccountID = value.ID;
                    }
                }
                else
                {
                    _Account = value;
                }
            }
        }
        #endregion

        #region Category
        public IAccountingCategory Category
        {
            get
            {
                if (_CategoryID != Guid.Empty)
                {
                    return ApplicationModel.Accounting.Categories[_CategoryID];
                }
                else
                {
                    return null;
                }
            }

            set
            {
                if (value == null)
                {
                    _CategoryID = Guid.Empty;
                }
                else
                {
                    CategoryID = value.ID;
                }
            }
        }
        #endregion

        #region Project
        public IProject Project
        {
            get
            {
                if (_ProjectID.HasValue)
                {
                    return ApplicationModel.Project.Projects[_ProjectID.Value];
                }
                else
                {
                    return null;
                }
            }

            set
            {
                if (value == null)
                {
                    ProjectID = null;
                }
                else
                {
                    ProjectID = value.ID;
                }
            }
        }
        #endregion

        #endregion

        internal AccountOperation()
        {
            _Amount = 0;
            _ExecutionDate = DateTime.Today;
        }

        internal AccountOperation(AccountOperation P_User)
            : base((LunaEntity)P_User)
        {
            CopyValues(P_User);
            AcceptChanges();
        }

        internal AccountOperation(IAccountOperation P_User, Account P_ParentAccount)
            : base((LunaEntity)P_User)
        {
            CopyValues(P_User);
            _Account = P_ParentAccount;
            AcceptChanges();
        }

        internal AccountOperation(IAccountOperationData P_UserData)
            : base(P_UserData)
        {
            LoadData(P_UserData);
            AcceptChanges();
        }

        public void CopyValues(IAccountOperation P_Clone)
        {
            Account = P_Clone.Account;
            Category = P_Clone.Category;
            Project = P_Clone.Project;
            Amount = P_Clone.Amount;
            Description = P_Clone.Description;
            ExecutionDate = P_Clone.ExecutionDate;
            OperationType = P_Clone.OperationType;
            ValueDate = P_Clone.ValueDate;
        }

        private void LoadData(IAccountOperationData P_Data)
        {
            _AccountID = P_Data.AccountID;
            _Amount = P_Data.Amount;
            _CategoryID = P_Data.CategoryID;
            _ProjectID = P_Data.ProjectID;
            _Description = P_Data.Description;
            _ExecutionDate = P_Data.ExecutionDate;
            _OperationType = P_Data.OperationType;
            _ValueDate = P_Data.ValueDate;
        }
    }
}
